
/*========================================================================================
 *                                                                                      *
 *               Copyright(c) 2013-2014, Cha SangWoo, All rights reserved.              *
 *                                                                                      *
 * This file is part of ChaOS.                                                          *
 *                                                                                      *
 * Permission to use, copy, modify, and distribute this software in source and binary   *
 * forms and its documentation for any purpose and without fee is hereby granted,       *
 * provided that the above copyright notice appear in all copies and that both that     *
 * copyright notice and this permission notice appear in supporting documentation.      *
 *                                                                                      *
 * THIS SOFTWARE IS PROVIDED BY THE CHA SANGWOO AND CONTRIBUTORS "AS IS" AND ANY        *
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED            *
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL CHA SANGWOO OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,    *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT         *
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,          *
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF            *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE      *
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                    *
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
 *                                                                                      *
========================================================================================*/

#ifndef __CO_STATE_ENGINE_H__
#define __CO_STATE_ENGINE_H__

//#include "co_port.h"
#include "co_types.h"
#include "co_log.h"

#if (FLAG_USE_CHAOS_STATE_ENGINE == CO_ENABLE)

#ifdef __cplusplus
    extern "C" {
    namespace ChaOS {
#endif

//////////////////////////////////////  < BEGIN >  ///////////////////////////////////////

//#define FLAG_USE_TRACE_CHAOS_STATE_ENGINE	CO_ENABLE
#define FLAG_USE_TRACE_CHAOS_STATE_ENGINE	CO_DISABLE

#define TYPE_START          (0xFFF1)
#define TYPE_EXIT           (0xFFF2)
#define TYPE_TIMEOUT        (0xFFF3)

#define CALL_RETURN         ((STATE)0xFFFFFFFA)

#define STATE_STAY()        ((STATE)NULL)
#define STATE_MOVE(state)   (TRACE_M("State Move to ", #state, state))
#define STATE_RETURN()      (TRACE_M("State Return  ", __FUNC__, CALL_RETURN))

#if (FLAG_USE_TRACE_CHAOS_STATE_ENGINE == CO_ENABLE)
    #define TRACE_M(msg, name, state)  (STATE)((_port_log_printf("STATE", msg name "\n")) ? (state) : (state))

#else
    #define TRACE_M(msg, name, state)  (STATE)(state)

#endif

/*======================================================================================*/
/*!
    @fn             OBJECT co_state_engine_create(VOID)

    @brief          

    @return         Object for state engine
*/
/*======================================================================================*/
OBJECT co_state_engine_create(OBJECT  objQueue, VOID   *puser_data);


/*======================================================================================*/
/*
    @fn             VOID    co_state_engine_set_name(OBJECT object, CHAR *pname)

    @brief          

    @param [in]     object - 
    @param [in]     pname - 

    @return         None.
*/
/*======================================================================================*/
#if (FLAG_USE_CHAOS_STATE_ENGINE_NAME == CO_ENABLE)
    VOID    co_state_engine_set_name(OBJECT object, CHAR *pname);

#else
    #define co_state_engine_set_name(object, pname)       DO_NOTHING

#endif


/*======================================================================================*/
/*!
    @fn             VOID co_state_engine_start(OBJECT object, STATE_PROC entry_state)

    @brief          

    @param [in]     object     - Object for state engine
    @param [in]     exit_state - 

    @return         None
*/
/*======================================================================================*/
VOID co_state_engine_start(OBJECT object, STATE_PROC entry_state);


/*======================================================================================*/
/*!
    @fn             VOID co_state_engine_call_state(OBJECT object, STATE_PROC exit_state)

    @brief          

    @param [in]     object     - Object for state engine
    @param [in]     exit_state - 

    @return         None
*/
/*======================================================================================*/
VOID co_state_engine_call_state(OBJECT object, STATE_PROC entry_state);


/*======================================================================================*/
/*!
    @fn             OBJECT co_state_engine_timer_create(OBJECT state_object)

    @brief          

    @param [in]     state_object - 

    @return         None
*/
/*======================================================================================*/
OBJECT co_state_engine_timer_create(OBJECT state_object);


/*======================================================================================*/
/*!
    @fn             VOID co_state_engine_timer_start(OBJECT timer_object, 
                                                     UINT16 id, 
                                                     UINT16 timeout, 
                                                     BOOL repeate)

    @brief          

    @param [in]     timer_object
    @param [in]     id
    @param [in]     timeout
    @param [in]     repeate

    @return         None
*/
/*======================================================================================*/
VOID co_state_engine_timer_start(OBJECT timer_object, 
                                 UINT16 id, 
                                 UINT16 timeout, 
                                 BOOL repeate);


/*======================================================================================*/
/*!
    @fn             VOID co_state_engine_timer_stop(OBJECT timer_object)

    @brief          

    @param [in]     timer_object

    @return         None
*/
/*======================================================================================*/
VOID co_state_engine_timer_stop(OBJECT timer_object);


//////////////////////////////////////  <  END  >  ///////////////////////////////////////

#ifdef __cplusplus
    } /* namespace ChaOS */
    } /* extern "C" */
#endif

#endif // (FLAG_USE_CHAOS_STATE_ENGINE == CO_ENABLE)

#endif //__CO_STATE_ENGINE_H__

